package geo
{
	import away3d.core.base.SubGeometry;
	import away3d.core.math.MathConsts;
	import away3d.core.math.Matrix3DUtils;
	import away3d.primitives.PrimitiveBase;
	
	import configs.MakerConfig;
	
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	
	/**
	 * 扇形
	 * 
	 * @custom 
	 * <author email="scutterry&#64;vip.qq.com">scutterry</author>
	 * <create>Sep 3, 2012</create>
	 * <modify>Sep 3, 2012</modify>
	 * <version>1.0</version>
	 */
	
	public class SectorGeometry extends PrimitiveBase
	{
		private var _angle:Number = 70;
		
		private var _rotation:Number = 0;
		
		private var _radius:Number = 1000;
		
		private var _position:Vector3D;
		
		private var _yUp : Boolean = true;
		
		/**
		 * 圆环宽度 
		 */		
		private var width:Number = MakerConfig.TRACK_WIDTH;
		
		
		private var numSegment:Number = 10;
		
		public function SectorGeometry()
		{
		}
		
		
		override protected function buildGeometry(target:SubGeometry):void{
			var vertices : Vector.<Number>;
			var normals : Vector.<Number>;
			var tangents : Vector.<Number>;
			var indices : Vector.<uint>;
			
			var numVerts : uint = (numSegment + 1) * 2;
			var index:uint = 0;
			var fidx:int = 0;
			var revolutionAngle:Number = 0;
			var revolutionAngleDelta:Number = _angle / numSegment * MathConsts.DEGREES_TO_RADIANS;
			var delta:Number = this._rotation * MathConsts.DEGREES_TO_RADIANS
			if (numVerts == target.numVertices) {
				vertices = target.vertexData;
				normals = target.vertexNormalData;
				tangents = target.vertexTangentData;
				indices = target.indexData;
			}
			else {
				vertices = new  Vector.<Number>(numVerts * 3, true);
				normals = new Vector.<Number>(numVerts * 3, true);
				tangents = new Vector.<Number>(numVerts * 3, true);
				indices = new Vector.<uint>(numSegment * 6, true);
			}
			
			var extX:Number, extY:Number, extZ:Number;//外圆坐标
			var intX:Number, intY:Number, intZ:Number;//内圆坐标
			var i:int;
			var vertexIndex:int = 0;
			for (i = 0; i <= numSegment; ++i) {
				revolutionAngle = i * revolutionAngleDelta;
				extX = Math.cos(revolutionAngle + delta) * _radius;
				extZ = Math.sin(revolutionAngle + delta) * _radius;
				intX = Math.cos(revolutionAngle + delta) * (_radius - width);
				intZ = Math.sin(revolutionAngle + delta) * (_radius - width);
				if(!_yUp){
					//external
					vertices[vertexIndex] = extX;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 1;
					
					vertices[vertexIndex] = -extZ;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 0;
					
					vertices[vertexIndex] = 0;
					normals[vertexIndex] = -1;
					tangents[vertexIndex++] = 0;
					
					
					//internal
					vertices[vertexIndex] = intX;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 1;
					
					vertices[vertexIndex] = -intZ;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 0;
					
					vertices[vertexIndex] = 0;
					normals[vertexIndex] = -1;
					tangents[vertexIndex++] = 0;
					
				} else{
					
					//external
					vertices[vertexIndex] = extX;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 1;
					
					vertices[vertexIndex] = 0;
					normals[vertexIndex] = 1;
					tangents[vertexIndex++] = 0;
					
					vertices[vertexIndex] = extZ;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 0;
					
					//internal
					vertices[vertexIndex] = intX;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 1;
					
					vertices[vertexIndex] = 0;
					normals[vertexIndex] = 1;
					tangents[vertexIndex++] = 0;
					
					vertices[vertexIndex] = intZ;
					normals[vertexIndex] = 0;
					tangents[vertexIndex++] = 0;
				}
					
				index = i * 2;
				// revolution vertex
				if(i > 0){// add triangle
					indices[fidx++] = index;
					indices[fidx++] = index - 2;
					indices[fidx++] = index - 1;
					
					
					indices[fidx++] = index;
					indices[fidx++] = index - 1;
					indices[fidx++] = index + 1;
				}
			}//for i
			
			target.updateVertexData(vertices);
			target.updateVertexNormalData(normals);
			target.updateVertexTangentData(tangents);
			target.updateIndexData(indices);
			
		}
		
		override protected function buildUVs(target:SubGeometry):void{
			var numUvs : uint = (numSegment + 1) * 4;
			var uvData : Vector.<Number>;
			
//			var intCircumference:Number = Math.PI * (this._radius - this.width) * 2;
//			var extCircumference:Number = Math.PI * _radius * 2;
			
			if (target.UVData && numUvs == target.UVData.length)
				uvData = target.UVData;
			else
				uvData = new Vector.<Number>(numUvs, true);
			var delta:Number = 1 / this.numSegment;
			for (var i:int = 0; i <= this.numSegment; i++){
				uvData[i * 4 + 1] = 1;
				uvData[i * 4] = i * delta;
				
				uvData[i * 4 + 3] = 0;
				uvData[i * 4 + 2] = i * delta;
				
			}
			
			target.updateUVData(uvData);
		}
		
		
		/**
		 * 扇形角度 
		 */
		public function get angle():Number
		{
			return _angle;
		}

		/**
		 * @private
		 */
		public function set angle(p_value:Number):void
		{
			_angle = Math.min(p_value, 360);
			this.invalidateGeometry();
			this.invalidateUVs();
		}

		/**
		 * 旋转角度 
		 */
		public function get rotation():Number
		{
			return _rotation;
		}

		/**
		 * @private
		 */
		public function set rotation(p_value:Number):void
		{
			_rotation = p_value;
		}

		/**
		 * 半径 
		 */
		public function get radius():Number
		{
			return _radius;
		}

		/**
		 * @private
		 */
		public function set radius(p_value:Number):void
		{
			_radius = p_value;
			this.invalidateGeometry();
		}

		/**
		 * 圆心 
		 */
		public function get position():Vector3D
		{
			return _position;
		}

		/**
		 * @private
		 */
		public function set position(p_value:Vector3D):void
		{
			_position = p_value;
		}

		public function get yUp():Boolean
		{
			return _yUp;
		}

		public function set yUp(p_value:Boolean):void
		{
			_yUp = p_value;
			this.invalidateGeometry();
		}


	}//end class
}